import * as THREE from 'three';
import { City } from './City';

const SELECTED_COLOR = 0xaaaa55;
const HIGHLIGHTED_COLOR = 0x555555;

const vec3$1 = new THREE.Vector3();

export class SimObject extends THREE.Object3D {

    private _mesh: THREE.Object3D = null;

    get mesh() {
        return this._mesh;
    }

    get x() {
        this.getWorldPosition(vec3$1);
        return Math.floor(vec3$1.x);
    }

    get y() {
        this.getWorldPosition(vec3$1);
        return Math.floor(vec3$1.z);
    }

    constructor(x = 0, y = 0) {
        super();
        this.name = 'SimObject';
        this.position.x = x;
        this.position.z = y;
    }

    setMesh(value: THREE.Object3D) {
        // Remove resources for existing mesh
        if (this._mesh) {
            this.dispose();
            this.remove(this._mesh);
        }

        this._mesh = value;

        // Add to scene graph
        if (this._mesh) {
            this.add(this._mesh);
        }
    }

    simulate(city: City) {
        // Override in subclass
    }

    setSelected(value: boolean) {
        if (value) {
            this.setMeshEmission(SELECTED_COLOR);
        } else {
            this.setMeshEmission(0);
        }
    }

    setFocused(value: boolean) {
        if (value) {
            this.setMeshEmission(HIGHLIGHTED_COLOR);
        } else {
            this.setMeshEmission(0);
        }
    }

    private setMeshEmission(color: number) {

        if (!this._mesh) return;
        this._mesh.traverse((obj) => {
            if (obj instanceof THREE.Mesh) {
                obj.material?.emissive?.setHex(color);
            }
        });
    }

    /**
     * Handles any clean up needed before an object is removed
     */
    dispose() {
        this._mesh.traverse((obj) => {
            if (obj instanceof THREE.Mesh) {
                obj.material.dispose();
            }
        });
    }

    toHTML(): string {

        return "no information";

    }
}